#include <stdio.h>
#include <string.h>
#include "esp_log.h"
#include "esp_wifi.h"
#include "nvs_flash.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_task_wdt.h"

// 程序功能：2023.4.2——ESP-IDF 使用event_loop扫描WIFI
//      1.先创建一个默认的event_loop队列
//      2.然后创建一个app_task，在其中对WIFI的事件类型和ID进行注册，如果监听到就触发run_on_event函数
//      3.由于run_on_event其实就是在event_loop，event_loop系统分配的堆栈很小，所以不能在run_on_event进行大动作
//        所以只能在event_loop中对事件ID进行判断，从而创建对应的任务进行处理
//      4.可以在触发事件后回调函数中进行id的判断

void wifi_scan_task(void *pt)
{
    ESP_LOGI("WIFI", "4. Wi-Fi 扫描");
    wifi_country_t wifi_country_config = {
        .cc = "CN",
        .schan = 1,
        .nchan = 13,
    };
    ESP_ERROR_CHECK(esp_wifi_set_country(&wifi_country_config));
    ESP_ERROR_CHECK(esp_wifi_scan_start(NULL, false));

    vTaskDelete(NULL);
}

void wifi_scan_show(void *pt)
{
    uint16_t ap_num = 0;
    ESP_ERROR_CHECK(esp_wifi_scan_get_ap_num(&ap_num));
    ESP_LOGI("WIFI", "AP Count : %d", ap_num);

    uint16_t max_aps = 20;
    wifi_ap_record_t ap_records[max_aps];
    memset(ap_records, 0, sizeof(ap_records));

    uint16_t aps_count = max_aps;
    ESP_ERROR_CHECK(esp_wifi_scan_get_ap_records(&aps_count, ap_records));

    ESP_LOGI("WIFI", "AP Count: %d", aps_count);

    printf("%30s %s %s %s\n", "SSID", "频道", "强度", "MAC地址");

    for (int i = 0; i < aps_count; i++)
    {
        printf("%30s  %3d  %3d  %02X-%02X-%02X-%02X-%02X-%02X\n", ap_records[i].ssid, ap_records[i].primary, ap_records[i].rssi, ap_records[i].bssid[0], ap_records[i].bssid[1], ap_records[i].bssid[2], ap_records[i].bssid[3], ap_records[i].bssid[4], ap_records[i].bssid[5]);
    }

    vTaskDelete(NULL);
}

void run_on_event(void *handler_arg, esp_event_base_t base, int32_t id, void *event_data)
{
    ESP_LOGE("EVENT_HANDLE", "BASE:%s, ID:%d", base, id);

    switch (id)
    {
    case WIFI_EVENT_STA_START:
        ESP_LOGE("EVENT_HANDLE", "WIFI_EVENT_STA_START");
        xTaskCreate(wifi_scan_task, "wifi scan task", 1024 * 12, NULL, 1, NULL);
        break;
    case WIFI_EVENT_SCAN_DONE:
        ESP_LOGE("EVENT_HANDLE", "WIFI_EVENT_SCAN_DONE");
        xTaskCreate(wifi_scan_show, "wifi scan show", 1024 * 12, NULL, 1, NULL);
        break;
    default:
        break;
    }
}

void app_task(void *pt)
{
    ESP_LOGI("APP_TASK", "APP Task 创建完成");
    esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, run_on_event, NULL);
    while (1)
    {
        // ESP_LOGI("APP_TASK", "APP Task 无聊的运行中");
        vTaskDelay(1000 / portTICK_PERIOD_MS);
    }
}

void app_main(void)
{
    ESP_LOGI("WIFI", "0. 初始化NVS存储");
    esp_err_t ret = nvs_flash_init();
    if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND)
    {
        ESP_ERROR_CHECK(nvs_flash_erase());
        ret = nvs_flash_init();
    }
    ESP_ERROR_CHECK(ret);

    ESP_LOGI("WIFI", "1. Wi-Fi 初始化阶段");
    ESP_ERROR_CHECK(esp_netif_init());
    ESP_ERROR_CHECK(esp_event_loop_create_default());
    esp_netif_create_default_wifi_sta();

    wifi_init_config_t wifi_config = WIFI_INIT_CONFIG_DEFAULT();
    ESP_ERROR_CHECK(esp_wifi_init(&wifi_config));

    xTaskCreate(app_task, "App Task", 1024 * 12, NULL, 1, NULL);

    ESP_LOGI("WIFI", "2. Wi-Fi 初始化阶段");
    ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));

    ESP_LOGI("WIFI", "3. Wi-Fi 启动阶段");
    ESP_ERROR_CHECK(esp_wifi_start());

    while (1)
    {
        // ESP_LOGI("MAIN_TASK", "MAIN Task 无聊的运行中");
        vTaskDelay(1000 / portTICK_PERIOD_MS);
    }
}
